package com.lindroy.androidplayer.utils

import androidx.lifecycle.LifecycleOwner
import androidx.lifecycle.LiveData
import androidx.lifecycle.MediatorLiveData
import androidx.lifecycle.Observer
import com.elvishew.xlog.XLog
import java.util.concurrent.atomic.AtomicBoolean

/**
 * @author Lin
 * @date 2021/8/24
 * @function 替换原生的 map 和 switchMap，解决数据倒灌问题
 */
class SingleMediatorLiveData<T> : MediatorLiveData<T>() {

    private val mPending = AtomicBoolean(false)

    override fun observe(owner: LifecycleOwner, observer: Observer<in T>) {

        /**
         * Todo(bug：只有第一次和最后一次的 postvalue 才会调用 observe)
         */
        super.observe(owner) {
            if (mPending.compareAndSet(true, false)) {
                observer.onChanged(it)
            }
        }
    }

    override fun postValue(value: T) {
        mPending.set(true)
        super.postValue(value)
    }

    override fun setValue(value: T) {
        mPending.set(true)
        super.setValue(value)
    }
}

inline fun <X, Y> LiveData<X>.mapSingle(crossinline transform: (X) -> Y): LiveData<Y> =
    SingleMediatorLiveData<Y>().let {
        it.addSource(this) { x ->
            it.postValue(transform(x))
        }
        it
    }

inline fun <X, Y> LiveData<X>.switchMapSingle(crossinline transform: (X) -> LiveData<Y>): LiveData<Y> =
    SingleMediatorLiveData<Y>().let { result ->
        result.addSource(this) { x ->
            var source: LiveData<Y>? = null
            val newLiveData = transform(x)
            if (source === newLiveData) {
                return@addSource
            }
            source?.also { result.removeSource(it) }
            source = newLiveData
            source.also {
                result.addSource(it) { y ->
                    result.setValue(y)
                }
            }
        }
        result
    }